package com.skt.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.skt.domain.PO.RentalOrder;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;

@Mapper
public interface RentalOrderMapper extends BaseMapper<RentalOrder> {

    /**
     * 判断指定服装是否存在“已取货但未归还”的租赁订单
     *
     * @param costumeId 服装ID
     * @return true 表示存在未归还订单，不能下架
     */
    @Select("""
        SELECT EXISTS (
            SELECT 1
            FROM rental_order ro
            INNER JOIN rental_order_item roi ON ro.id = roi.order_id
            WHERE roi.costume_id = #{costumeId}
              AND ro.status = 4
        )
        """)
    boolean existsUnreturnedByCostumeId(@Param("costumeId") Long costumeId);

    /**
     * 商家发货：将状态从 2（已支付）更新为 3（已发货），并记录发货时间
     *
     * @param orderId        订单ID
     * @param merchantId     商家ID（用于权限校验）
     * @param expectedStatus 预期当前状态（应为 2）
     * @param newStatus      新状态（应为 3）
     * @param shipTime       发货时间
     * @return 受影响行数（0 表示并发冲突或条件不满足）
     */
    @Update("""
        UPDATE rental_order
        SET 
            status = #{newStatus},
            ship_time = #{shipTime},
            updated_at = NOW()
        WHERE 
            id = #{orderId}
            AND merchant_id = #{merchantId}
            AND status = #{expectedStatus}
        """)
    int updateForShip(
            @Param("orderId") Long orderId,
            @Param("merchantId") Long merchantId,
            @Param("expectedStatus") Integer expectedStatus,
            @Param("newStatus") Integer newStatus,
            @Param("shipTime") java.time.LocalDateTime shipTime
    );

    /**
     * 商家确认归还：将订单状态从“已取货”(4) 更新为“已归还”(5)，并记录归还时间
     *
     * @param id         订单ID
     * @param merchantId 商家ID
     * @param oldStatus  预期旧状态（应为 4）
     * @param newStatus  新状态（应为 5）
     * @param returnedAt 归还完成时间
     * @return 受影响行数（0 表示并发冲突或状态不符）
     */
    @Update("""
        UPDATE rental_order
        SET 
            status = #{newStatus},
            returned_at = #{returnedAt},
            updated_at = NOW()
        WHERE 
            id = #{id}
            AND merchant_id = #{merchantId}
            AND status = #{oldStatus}
        """)
    int updateStatusByIdAndMerchantAndStatus(
            @Param("id") Long id,
            @Param("merchantId") Long merchantId,
            @Param("oldStatus") Integer oldStatus,
            @Param("newStatus") Integer newStatus,
            @Param("returnedAt") java.time.LocalDateTime returnedAt
    );

    /**
     * 查询商家在指定时间范围内的已完成订单总收入（状态=5）
     */
    @Select("""
        SELECT COALESCE(SUM(total_amount), 0)
        FROM rental_order
        WHERE merchant_id = #{merchantId}
          AND created_at >= #{startTime}
          AND created_at < #{endTime}
          AND status = 5
        """)
    BigDecimal selectTotalIncomeByMerchantAndTime(
            @Param("merchantId") Long merchantId,
            @Param("startTime") java.time.LocalDateTime startTime,
            @Param("endTime") java.time.LocalDateTime endTime
    );

    /**
     * 查询商家在指定时间范围内“当前处于租赁中”的服装总件数（状态为 3=已发货 或 4=已取货）
     */
    @Select("""
        SELECT COUNT(*)
        FROM rental_order ro
        INNER JOIN rental_order_item roi ON ro.id = roi.order_id
        WHERE ro.merchant_id = #{merchantId}
          AND ro.created_at >= #{startTime}
          AND ro.created_at < #{endTime}
          AND ro.status IN (3, 4)
        """)
    long selectRentingCountByMerchant(
            @Param("merchantId") Long merchantId,
            @Param("startTime") java.time.LocalDateTime startTime,
            @Param("endTime") java.time.LocalDateTime endTime
    );

    /**
     * 查询热门服装 TOP5（按租赁次数降序）
     */
    @Select("""
        SELECT 
            roi.costume_id AS costumeId,
            c.name AS costumeName,
            COUNT(*) AS rentalCount
        FROM rental_order ro
        INNER JOIN rental_order_item roi ON ro.id = roi.order_id
        INNER JOIN costume c ON roi.costume_id = c.id
        WHERE ro.merchant_id = #{merchantId}
          AND ro.created_at >= #{startTime}
          AND ro.created_at < #{endTime}
          AND ro.status IN (3, 4, 5)
        GROUP BY roi.costume_id, c.name
        ORDER BY rentalCount DESC
        LIMIT 5
        """)
    List<Map<String, Object>> selectHotCostumesByMerchant(
            @Param("merchantId") Long merchantId,
            @Param("startTime") java.time.LocalDateTime startTime,
            @Param("endTime") java.time.LocalDateTime endTime
    );

    /**
     * 根据订单编号（orderNo）查询订单
     */
    @Select("SELECT * FROM rental_order WHERE order_no = #{orderNo}")
    RentalOrder selectByOrderNo(String orderNo);

    /**
     * 根据用户ID查询订单
     * @param userId
     * @return
     */
    @Select("SELECT * FROM rental_order WHERE user_id = #{userId}")
    RentalOrder selectByUserId(Long userId);

    IPage<RentalOrder> selectOrdersByMerchant(
            @Param("page") IPage<RentalOrder> page,
            @Param("merchantId") Long merchantId,
            @Param("status") Integer status,
            @Param("startDateFrom") LocalDate startDateFrom,
            @Param("startDateTo") LocalDate startDateTo,
            @Param("endDateFrom") LocalDate endDateFrom,
            @Param("endDateTo") LocalDate endDateTo
    );

}